package tripleheap;

import java.io.*;
import java.lang.*;
import global.*;
import tripleheap.FieldNumberOutOfBoundException;


public class Triple implements GlobalConst{
	/** 
	  * Maximum size of any tuple
	  */
	  public static final int max_size = MINIBASE_PAGESIZE;

	 /** 
	   * a byte array to hold data
	   */
	  private byte [] data;

	  /**
	   * start position of this tuple in data[]
	   */
	  private int triple_offset;

	  /**
	   * length of this tuple
	   */
	  //------------------------------------------------------------------------------------------------------
	  private int triple_length = 32;

	  /** 
	   * private field
	   * Number of fields in this tuple
	   */
	  private short fldCnt=4;
	  
	  public EID sub = new EID();
	  public PID pre = new PID();
	  public EID obj = new EID();
	  public double attrReal;
	  /** 
	   * private field
	   * Array of offsets of the fields
	   */
	 
	  private short [] fldOffset; 

	   /**
	    * Class constructor
	    * Creat a new tuple with length = max_size,tuple offset = 0.
	    */

	  public  Triple()
	  {
	       // Creat a new tuple
	       data = new byte[max_size];
	       triple_offset = 0;
	       triple_length = max_size;
	  }

	   public Triple(byte [] atriple, int offset, int length)
	   {
	      data = atriple;
	      triple_offset = offset;
	      triple_length = length;
	    //  fldCnt = getShortValue(offset, data);
	   }
	   
	   public int getOffset()
	   {
	      return triple_offset;
	   } 
	   
	   public byte [] returnTripleByteArray()
	   {
	       return data;
	   }
	   
	   /** Constructor(used as tuple copy)
	    * @param fromTuple   a byte array which contains the tuple
	    * 
	    */
	   public Triple(Triple fromTriple)
	   {
	       data = fromTriple.getTripleByteArray();
	       triple_length = fromTriple.getLength();
	       triple_offset = 0;
	       fldCnt = 4;
	       sub = fromTriple.sub;
	       pre = fromTriple.pre;
	       obj = fromTriple.obj;
	       attrReal = fromTriple.attrReal;
//	       fldCnt = fromTriple.noOfFlds(); 
	       fldOffset = fromTriple.copyFldOffset(); 
	   }

	private short[] copyFldOffset() {
		// TODO Auto-generated method stub
		  short[] newFldOffset = new short[fldCnt + 1];
		     for (int i=0; i<=fldCnt; i++) {
		       newFldOffset[i] = fldOffset[i];
		     }
		     
		     return newFldOffset;
	}

	private short noOfFlds() {
		// TODO Auto-generated method stub
		return 4;
	}

	public int getLength() {
		return triple_length;
		//		// TODO Auto-generated method stub
	}
	
	   public EID getSubjectID(){
		   return sub;
	   }
	   public EID getObjectID(){
		   return obj;
	   }
	   public PID getPredicateID(){
		   return pre;
	   }
	   public double getConfidance()
	   {
		   return attrReal;
	   }
	   
	   
	   Triple setSubjectID(EID subjectID){
		sub = subjectID;
		return this;
		   //return sub;
		   
		   
	   }
	   Triple setObjectID(EID objectID){
		   obj = objectID;
		   
		   return this;
		   
		   
	   }
	   Triple setPredicateID(PID predicateID){
		pre = predicateID;
		   return this;
		   
	   }
	   Triple setConfidence(double confidence){
		   attrReal = confidence;
		   return this;
			   
		   }
	   
	   
public void print(AttrType type[])
	    throws IOException 
	 {
	  int i;// val;
	 // float fval;
	 // String sval;

	  System.out.print("[");
	  	 int sub = Convert.getIntValue(fldOffset[0], data);
	     System.out.print(sub);
	     
	     int pre = Convert.getIntValue(fldOffset[1], data);
	     System.out.print(pre);
	   
	     int obj = Convert.getIntValue(fldOffset[2], data);
	     System.out.print(obj);
	     
	     double val = Convert.getDblValue(fldOffset[3], data);
	     System.out.print(val);
	     	     
	 //    System.out.print(", ");
	  
	 	   System.out.println("]");

	 }
	/*public String getStrFld(int fldNo){
		return (Convert.getStrValue(fldNo-1, data, fldOffset[fldNo]-fldOffset[fldNo-1]));
	}*/
     	public String getStrFld(int fldNo) 
	   	throws IOException, FieldNumberOutOfBoundException 
	   { 
	         String val;
	    if ( (fldNo > 0) && (fldNo <= fldCnt))      
	     {
	        val = Convert.getStrValue1(fldOffset[fldNo -1], data, 
			fldOffset[fldNo] - fldOffset[fldNo -1]); //strlen+2
	        return val;
	     }
	    else 
	     throw new FieldNumberOutOfBoundException (null, "TUPLE:TUPLE_FLDNO_OUT_OF_BOUND");
	  }

	   public short size()
	    {
	       return ((short) (fldOffset[fldCnt] - triple_offset));
	    }
	   
	   public void tripleCopy(Triple fromTriple)
	   {
	       byte [] temparray = fromTriple.getTripleByteArray();
	       System.arraycopy(temparray, 0, data, triple_offset, triple_length);   
//	       fldCnt = fromTuple.noOfFlds(); 
//	       fldOffset = fromTuple.copyFldOffset(); 
	   }

	public byte[] getTripleByteArray() {
		// TODO Auto-generated method stub
	//	return null;
	
		 byte [] triplecopy = new byte [triple_length];
	       System.arraycopy(data, triple_offset, triplecopy, 0, triple_length);
	       return triplecopy;
	   
	}
	   
	 
	   public void tripleInit(byte [] atriple, int offset)
	   {
		   int length=32;
	      data = atriple;
	      triple_offset = offset;
	      triple_length = length;
	   }

	 public void tripleSet(byte [] record, int offset)  
	  {
		  
	      System.arraycopy(record, offset, data, 0, triple_length);
	      triple_offset = 0;
//	      triple_length = length;
	  }
	 

}
